package com.zenithmind.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.mall.mapper.OrderItemMapper;
import com.zenithmind.mall.mapper.OrderMapper;
import com.zenithmind.mall.mapper.ProductMapper;
import com.zenithmind.mall.pojo.dto.OrderItemDTO;
import com.zenithmind.mall.pojo.entity.OrderItem;
import com.zenithmind.mall.pojo.entity.Order;
import com.zenithmind.mall.pojo.entity.Product;
import com.zenithmind.mall.pojo.query.OrderItemQuery;
import com.zenithmind.mall.pojo.vo.OrderItemVO;
import com.zenithmind.mall.service.OrderItemService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单详情服务实现
 * 
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderItemServiceImpl extends ServiceImpl<OrderItemMapper, OrderItem> implements OrderItemService {

    private final OrderMapper orderMapper;
    private final ProductMapper productMapper;

    @Override
    public PageResult<OrderItemVO> getOrderItemPage(OrderItemQuery query) {
        Page<OrderItem> page = new Page<>(query.getCurrent(), query.getSize());
        
        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderItem::getIsDeleted, 0)
               .eq(StringUtils.hasText(query.getOrderId()), OrderItem::getOrderId, query.getOrderId())
               .eq(StringUtils.hasText(query.getProductId()), OrderItem::getProductId, query.getProductId())
               .like(StringUtils.hasText(query.getProductName()), OrderItem::getProductName, query.getProductName())
               .eq(StringUtils.hasText(query.getProductSku()), OrderItem::getProductSku, query.getProductSku())
               .ge(query.getMinPrice() != null, OrderItem::getProductPrice, query.getMinPrice())
               .le(query.getMaxPrice() != null, OrderItem::getProductPrice, query.getMaxPrice())
               .ge(query.getMinQuantity() != null, OrderItem::getQuantity, query.getMinQuantity())
               .le(query.getMaxQuantity() != null, OrderItem::getQuantity, query.getMaxQuantity())
               .ge(query.getMinTotalAmount() != null, OrderItem::getTotalAmount, query.getMinTotalAmount())
               .le(query.getMaxTotalAmount() != null, OrderItem::getTotalAmount, query.getMaxTotalAmount())
               .eq(query.getIsReviewed() != null, OrderItem::getIsReviewed, query.getIsReviewed())
               .ge(query.getStartTime() != null, OrderItem::getCreateTime, query.getStartTime())
               .le(query.getEndTime() != null, OrderItem::getCreateTime, query.getEndTime());

        // 如果指定了用户ID，需要通过订单表关联查询
        if (StringUtils.hasText(query.getUserId())) {
            // 先查询用户的订单ID列表
            LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
            orderWrapper.eq(Order::getUserId, query.getUserId())
                       .eq(Order::getIsDeleted, 0)
                       .select(Order::getId);
            List<Order> orders = orderMapper.selectList(orderWrapper);
            List<String> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
            
            if (orderIds.isEmpty()) {
                return new PageResult<>(List.of(), 0L, page.getCurrent(), page.getSize());
            }
            wrapper.in(OrderItem::getOrderId, orderIds);
        }

        // 排序
        if (StringUtils.hasText(query.getSortField())) {
            boolean isAsc = "asc".equalsIgnoreCase(query.getSortOrder());
            switch (query.getSortField()) {
                case "productPrice":
                    wrapper.orderBy(true, isAsc, OrderItem::getProductPrice);
                    break;
                case "quantity":
                    wrapper.orderBy(true, isAsc, OrderItem::getQuantity);
                    break;
                case "totalAmount":
                    wrapper.orderBy(true, isAsc, OrderItem::getTotalAmount);
                    break;
                default:
                    wrapper.orderByDesc(OrderItem::getCreateTime);
            }
        } else {
            wrapper.orderByDesc(OrderItem::getCreateTime);
        }

        Page<OrderItem> result = page(page, wrapper);

        // 转换为VO
        List<OrderItemVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public OrderItemVO getOrderItemById(String id) {
        OrderItem orderItem = getById(id);
        if (orderItem == null) {
            throw new BusinessException("订单详情不存在");
        }
        return convertToVO(orderItem);
    }

    @Override
    public List<OrderItemVO> getOrderItemsByOrderId(String orderId) {
        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderItem::getOrderId, orderId)
               .eq(OrderItem::getIsDeleted, 0)
               .orderByAsc(OrderItem::getCreateTime);

        List<OrderItem> orderItems = list(wrapper);
        return orderItems.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createOrderItem(OrderItemDTO orderItemDTO) {
        // 验证商品是否存在
        Product product = productMapper.selectById(orderItemDTO.getProductId());
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        OrderItem orderItem = new OrderItem();
        BeanUtils.copyProperties(orderItemDTO, orderItem);
        
        // 设置商品信息
        orderItem.setProductName(product.getName());
        orderItem.setProductImage(product.getMainImage());
        orderItem.setIsReviewed(0); // 默认未评价
        orderItem.setCreateBy(UserContext.getUserId());

        if (!save(orderItem)) {
            throw new BusinessException("创建订单详情失败");
        }

        log.info("创建订单详情成功: {}", orderItem.getId());
        return orderItem.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createOrderItemsBatch(List<OrderItemDTO> orderItemDTOs) {
        if (orderItemDTOs == null || orderItemDTOs.isEmpty()) {
            return true;
        }

        List<OrderItem> orderItems = orderItemDTOs.stream().map(dto -> {
            // 验证商品是否存在
            Product product = productMapper.selectById(dto.getProductId());
            if (product == null) {
                throw new BusinessException("商品不存在: " + dto.getProductId());
            }

            OrderItem orderItem = new OrderItem();
            BeanUtils.copyProperties(dto, orderItem);
            
            // 设置商品信息
            orderItem.setProductName(product.getName());
            orderItem.setProductImage(product.getMainImage());
            orderItem.setIsReviewed(0); // 默认未评价
            orderItem.setCreateBy(UserContext.getUserId());
            
            return orderItem;
        }).collect(Collectors.toList());

        boolean result = saveBatch(orderItems);
        if (result) {
            log.info("批量创建订单详情成功: {} 条", orderItems.size());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateOrderItem(String id, OrderItemDTO orderItemDTO) {
        OrderItem orderItem = getById(id);
        if (orderItem == null) {
            throw new BusinessException("订单详情不存在");
        }

        // 验证商品是否存在
        Product product = productMapper.selectById(orderItemDTO.getProductId());
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        // 更新订单详情信息
        BeanUtils.copyProperties(orderItemDTO, orderItem);
        orderItem.setProductName(product.getName());
        orderItem.setProductImage(product.getMainImage());
        orderItem.setUpdateBy(UserContext.getUserId());

        boolean result = updateById(orderItem);
        if (result) {
            log.info("更新订单详情成功: {}", id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteOrderItem(String id) {
        OrderItem orderItem = getById(id);
        if (orderItem == null) {
            throw new BusinessException("订单详情不存在");
        }

        boolean result = removeById(id);
        if (result) {
            log.info("删除订单详情成功: {}", id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteOrderItemsByOrderId(String orderId) {
        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderItem::getOrderId, orderId)
               .eq(OrderItem::getIsDeleted, 0);

        boolean result = remove(wrapper);
        if (result) {
            log.info("删除订单详情成功，订单ID: {}", orderId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteOrderItemsBatch(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }

        boolean result = removeByIds(ids);
        if (result) {
            log.info("批量删除订单详情成功: {}", ids);
        }
        return result;
    }

    @Override
    public PageResult<OrderItemVO> getUserPurchasedProducts(String userId, Integer pageNum, Integer pageSize) {
        Page<OrderItem> page = new Page<>(pageNum, pageSize);

        // 先查询用户的已完成订单ID列表
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getUserId, userId)
                   .eq(Order::getStatus, 4) // 假设4表示已完成
                   .eq(Order::getIsDeleted, 0)
                   .select(Order::getId);
        List<Order> orders = orderMapper.selectList(orderWrapper);

        if (orders.isEmpty()) {
            return new PageResult<>(List.of(), 0L, page.getCurrent(), page.getSize());
        }

        List<String> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());

        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderItem::getOrderId, orderIds)
               .eq(OrderItem::getIsDeleted, 0)
               .orderByDesc(OrderItem::getCreateTime);

        Page<OrderItem> result = page(page, wrapper);

        // 转换为VO
        List<OrderItemVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public Boolean hasUserPurchasedProduct(String userId, String productId) {
        // 先查询用户的已完成订单ID列表
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getUserId, userId)
                   .eq(Order::getStatus, 4) // 假设4表示已完成
                   .eq(Order::getIsDeleted, 0)
                   .select(Order::getId);
        List<Order> orders = orderMapper.selectList(orderWrapper);

        if (orders.isEmpty()) {
            return false;
        }

        List<String> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());

        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderItem::getOrderId, orderIds)
               .eq(OrderItem::getProductId, productId)
               .eq(OrderItem::getIsDeleted, 0);

        return count(wrapper) > 0;
    }

    @Override
    public ProductSalesStatistics getProductSalesStatistics(String productId) {
        // 查询商品信息
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        // 查询已完成订单的商品销售数据
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getStatus, 4) // 假设4表示已完成
                   .eq(Order::getIsDeleted, 0)
                   .select(Order::getId);
        List<Order> completedOrders = orderMapper.selectList(orderWrapper);

        if (completedOrders.isEmpty()) {
            return new ProductSalesStatistics(productId, product.getName(), 0, 0, BigDecimal.ZERO);
        }

        List<String> orderIds = completedOrders.stream().map(Order::getId).collect(Collectors.toList());

        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderItem::getOrderId, orderIds)
               .eq(OrderItem::getProductId, productId)
               .eq(OrderItem::getIsDeleted, 0);

        List<OrderItem> orderItems = list(wrapper);

        if (orderItems.isEmpty()) {
            return new ProductSalesStatistics(productId, product.getName(), 0, 0, BigDecimal.ZERO);
        }

        // 计算统计数据
        Integer totalQuantity = orderItems.stream().mapToInt(OrderItem::getQuantity).sum();
        Integer orderCount = orderItems.size();
        BigDecimal totalAmount = orderItems.stream()
                .map(OrderItem::getTotalAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        return new ProductSalesStatistics(productId, product.getName(), totalQuantity, orderCount, totalAmount);
    }

    @Override
    public List<OrderItemVO> getHotSellingProducts(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        // 先查询已完成订单ID列表
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getStatus, 4) // 假设4表示已完成
                   .eq(Order::getIsDeleted, 0)
                   .select(Order::getId);
        List<Order> completedOrders = orderMapper.selectList(orderWrapper);

        if (completedOrders.isEmpty()) {
            return List.of();
        }

        List<String> orderIds = completedOrders.stream().map(Order::getId).collect(Collectors.toList());

        // 查询热销商品（按销量排序）
        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderItem::getOrderId, orderIds)
               .eq(OrderItem::getIsDeleted, 0)
               .groupBy(OrderItem::getProductId)
               .orderByDesc(OrderItem::getQuantity)
               .last("LIMIT " + limit);

        List<OrderItem> orderItems = list(wrapper);
        return orderItems.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public List<OrderItemVO> getUserRepurchaseProducts(String userId, Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        // 先查询用户的已完成订单ID列表
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getUserId, userId)
                   .eq(Order::getStatus, 4) // 假设4表示已完成
                   .eq(Order::getIsDeleted, 0)
                   .select(Order::getId);
        List<Order> orders = orderMapper.selectList(orderWrapper);

        if (orders.isEmpty()) {
            return List.of();
        }

        List<String> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());

        // 查询用户复购商品（同一商品购买次数大于1）
        LambdaQueryWrapper<OrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderItem::getOrderId, orderIds)
               .eq(OrderItem::getIsDeleted, 0)
               .groupBy(OrderItem::getProductId)
               .having("COUNT(*) > 1")
               .orderByDesc(OrderItem::getCreateTime)
               .last("LIMIT " + limit);

        List<OrderItem> orderItems = list(wrapper);
        return orderItems.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    /**
     * 转换为VO
     */
    private OrderItemVO convertToVO(OrderItem orderItem) {
        OrderItemVO vo = new OrderItemVO();
        BeanUtils.copyProperties(orderItem, vo);
        return vo;
    }
}
